#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include <unistd.h>

#define NUM_THREADS 2       // 线程数
#define NUM_TESTS 100      // 每个线程执行的操作次数

sem_t semaphore;          // 信号量

double total_time = 0.0;  // 记录总时间
pthread_mutex_t time_lock = PTHREAD_MUTEX_INITIALIZER;  // 用于保护 total_time 变量的锁

// 模拟操作的函数
void *test_semaphore(void *arg) {
    int i;
    struct timespec start_time, end_time;

    for (i = 0; i < NUM_TESTS; i++) {
        clock_gettime(CLOCK_MONOTONIC, &start_time);  // 获取操作开始时间

        sem_wait(&semaphore);  // 等待信号量

        // 模拟临界区操作
        usleep(10000);  // 模拟工作负载，延时10ms

        sem_post(&semaphore);  // 释放信号量

        clock_gettime(CLOCK_MONOTONIC, &end_time);  // 获取操作结束时间

        // 计算操作耗时（秒为单位）
        double elapsed_time = (end_time.tv_sec - start_time.tv_sec) +
                              (end_time.tv_nsec - start_time.tv_nsec) / 1.0e9;

        // 更新总时间
        pthread_mutex_lock(&time_lock);  // 锁住 total_time
        total_time += elapsed_time;
        pthread_mutex_unlock(&time_lock);  // 解锁 total_time
    }

    return NULL;
}

int userAppInit() {
    pthread_t threads[NUM_THREADS];  // 线程数组
    int i;

    // 初始化信号量，值为 1
    if (sem_init(&semaphore, 0, 1) != 0) {
        perror("sem_init failed");
        exit(1);
    }

    // 创建线程
    for (i = 0; i < NUM_THREADS; i++) {
        if (pthread_create(&threads[i], NULL, test_semaphore, NULL) != 0) {
            perror("pthread_create failed");
            exit(1);
        }
    }

    // 等待所有线程完成
    for (i = 0; i < NUM_THREADS; i++) {
        if (pthread_join(threads[i], NULL) != 0) {
            perror("pthread_join failed");
            exit(1);
        }
    }

    // 计算并输出平均混洗时间
    double avg_time = total_time / (NUM_THREADS * NUM_TESTS);
    printf("avg_time:%.9fs\n", avg_time);

    // 销毁信号量
    sem_destroy(&semaphore);

    return 0;
}

